# from langchain.text_splitter import CharacterTextSplitter,MarkdownTextSplitter,RecursiveCharacterTextSplitter
# from langchain.document_loaders import UnstructuredFileLoader,UnstructuredMarkdownLoader,UnstructuredWordDocumentLoader
import os
from fastapi import APIRouter, Query, UploadFile, File,Form,Body,Request
# from xingchen import Configuration, CharacterPermissionConfig,ApiClient, ChatApiSub, ChatReqParams,CharacterUpdateDTO, CharacterKey, Message, UserProfile, ModelParameters,ChatContext,CharacterCreateDTO,CharacterApiSub
import time

from typing import Optional
from pydantic import BaseModel
from embeddingDB import pgDB
from typing import Dict, Any
 
router = APIRouter(
    prefix= "/deviceBank",
    tags= ["deviceBankRouter"],
    responses= {404: {"description": "Not found path knowledge"}}
)



class userMessage(BaseModel):
    device_id: Optional[str] = ""
    nick_name: Optional[str] = ""
    user_id: Optional[str] = ""
    content: Optional[str] = ""

from fastapi.responses import StreamingResponse
# @router.post("/tts")
# async def tts(msg:userMessage):
#     return ""
    # return StreamingResponse(generate_text_from_xingchen(msg), media_type="text/plain")
# test_chat_async()
# test_chat_sync()

# work_dir = "."lm-qbcQwj0A9CKMEBu4YkVe6Q==

# 转换函数
def snake_to_camel(s: str) -> str:
    parts = s.split('_')
    return parts[0].lower() + ''.join(x.capitalize() for x in parts[1:])
 
# 递归转换字典键的函数
def convert_keys_to_camel(d: Dict[str, Any]) -> Dict[str, Any]:
    if isinstance(d, dict):
        return {snake_to_camel(k): convert_keys_to_camel(v) for k, v in d.items()}
    elif isinstance(d, list):
        return [convert_keys_to_camel(item) for item in d]
    else:
        return d
    
from datetime import datetime
class Device(BaseModel):
    id:Optional[int] = 0
    device_id: Optional[str] = ""
    name: Optional[str] = "尚未被主人起名的小新"
    introduction: Optional[str] = "主人太懒了，还没介绍这位小新同学"
    create_time: Optional[datetime] = ""
    update_time: Optional[datetime] = ""
    location: Optional[str] = "北京"
    memory: Optional[str] = ""
    role_agent_id: Optional[int] = 0
    history: Optional[list]=[]
    
class ChatRecord(BaseModel):
    id:Optional[int] = 0
    device_id: Optional[str] = ""
    device_device_id: Optional[str] = ""
    user_question: Optional[str] = ""
    assistant_reply: Optional[str] = ""
    create_time: Optional[datetime] = ""
    update_time: Optional[datetime] = ""
    
def getDeviceInfoByDeviceId(deviceId):
    
    db = pgDB()
    sql = '''
    SELECT device.*,role_agent.sound FROM device 
    LEFT JOIN role_agent
    ON role_agent.id = device.role_agent_id
    WHERE device_id='{}'
    '''.format(deviceId)
    print(sql)
    resp = db.select(sql)
    
    if resp is None or len(resp)==0:
        resp = None
    else:
        resp = resp[0]
    db.close()
    return resp
    

def getDeviceChatRecordByDeviceId(deviceId):
    
    db = pgDB()
    sql = '''
    SELECT * FROM device_chat_record
    WHERE device_device_id='{}' ORDER BY create_time DESC LIMIT 200
    '''.format(deviceId)
    print(sql)
    resp = db.select(sql)
    db.close()
    return resp
    
import requests
# 解析 IP 地址所在地的函数
def get_ip_location(ip_address: str) -> dict:
    # try:
    print(f"https://ipinfo.io/{ip_address}/json")
    response = requests.get(f"https://ipinfo.io/{ip_address}/json")
    resp = response.json()
    print(resp)
    return resp
    # except Exception as e:
    #     raise E(status_code=500, detail=f"Error fetching IP location: {str(e)}")
 

@router.post("/loginDevice")
def loginDevice(params:Device, request: Request):
    rs = {"code":200,"msg":"登录成功","data":{}}
    # 从请求中获取客户端 IP 地址
    client_ip = request.client.host
    # 如果使用反向代理，可能需要从 X-Forwarded-For 头中获取 IP 地址
    x_forwarded_for = request.headers.get('x-forwarded-for')
    if x_forwarded_for:
        # X-Forwarded-For 头可能包含多个 IP 地址，通常第一个是最原始的客户端 IP
        client_ip = x_forwarded_for.split(',')[0].strip()
 
    # 获取 IP 地址所在地
    location=""
    try:
        ip_location = get_ip_location(client_ip)
        location = ip_location["city"]
    except Exception as e:
        # 处理获取 IP 地址所在地时发生的错误
        location='中国'
        print( "IP定位异常：",e)
        
    db = pgDB()
    # sql = '''
    # SELECT * FROM device 
    # WHERE device_id='{}'
    # '''.format(params.device_id)
    # print(sql)
    # resp = db.select(sql)
    resp = getDeviceInfoByDeviceId(params.device_id)
    if resp is None or len(resp)==0:
        sql = '''
        INSERT INTO device(device_id,location)
        VALUES('{}','{}')
        '''.format(params.device_id,location)
        db.modify(sql)
        
    else:
        sql = '''
        UPDATE device SET login_time=NOW(),location='{}'
        WHERE device_id='{}'
        '''.format(location,params.device_id)
        db.modify(sql)
        
    # sql = '''
    # SELECT device.*,role_agent.sound FROM device 
    # LEFT JOIN role_agent
    # ON role_agent.id = device.role_agent_id
    # WHERE device_id='{}'
    # '''.format(params.device_id)
    # print(sql)
    # resp = db.select(sql)[0]
    
    resp = getDeviceInfoByDeviceId(params.device_id)
    db.close()
    rs["data"] = resp
    return rs
    
@router.post("/createDevice")
def createDevice(params:Device):
    rs = {"code":200,"msg":"创建成功","data":{}}
    location = '北京'
    sql = '''
    INSERT INTO device(name,introduction,device_id,location)
    VALUES('{}','{}','{}','{}')
    '''.format(params.name,params.device_id,params.introduction,location)
    db = pgDB()
    db.modify(sql)
    db.close()
    rs["data"] = {}
    return rs

import requests

@router.post("/postChatRecord")
def postChatRecord(params:ChatRecord):
    rs = {"code":200,"msg":"记录成功","data":{}}
    print("设备提交记录信息：",params)
    # device = getDeviceInfoByDeviceId(params.device_id)
    # if device is None:
    #     return  {"code":500,"msg":"记录失败","data":{}}
    # else
    sql = '''
    INSERT INTO device_chat_record(device_device_id,user_question,assistant_reply)
    VALUES('{}','{}','{}')
    '''.format(params.device_device_id,params.user_question,params.assistant_reply)
    db = pgDB()
    db.modify(sql)
    print("新增一个记录::",sql)
    sql = '''
    SELECT * FROM device_chat_record
    WHERE device_device_id = '{}' ORDER BY create_time desc
    '''.format(params.device_device_id)
    record = db.select(sql)
    content = '''
    <你的角色>
    你是聊天记录分析专家
    <你的任务>
    根据对话记录，请你帮我总结一个故事背景或线索，方便你和我共同保存聊天记忆。
    你只发给我故事记录即可，其他多余的话不要说。
    <对话记录>
    {}
    '''.format('\n'.join(['{}:{}\n{}:{}'.format("我",r["user_question"],"你",r["assistant_reply"]) for r in record])[:100000])
    header = {
    "Authorization": "Bearer fastgpt-pyhYXrdHtJgesG1UARULUradUsU8QTPVdGsHUYReMyxegKtbNPiFIJAXWRQvC",
    "Content-Type": "application/json",
    }
    reqParams = {"stream": False, "messages": [{"content": content, "role": "user"}]}
    resp = requests.post(
        "https://model.zscampus.com/api/v1/chat/completions", headers=header, json=reqParams
    )
    memory=""
    try:
        # print("记忆抽取")
        # print( resp.json())
        memory = resp.json()['choices'][0]['message']['content']
    except Exception as e:
        print("记忆抽取出问题",e)
        pass
    
    sql = '''
    UPDATE device SET memory='{}'
    WHERE device_id = '{}'
    '''.format(memory,params.device_device_id)
    db.modify(sql)
    
    db.close()
    rs["data"] = memory
    return rs

@router.post("/updateDevice")
def updateDevice(params:Device):
    rs = {"code":200,"msg":"创建成功","data":{}}
    # print("updateDevice:::",params)
    # name = params.name
    # print(params)
    # 角色管理准备部分已省略

    
    sql = '''
    UPDATE device
    SET name='{}',introduction='{}',role_agent_id='{}',location='{}'
    WHERE id='{}'
    
    '''.format(params.name,params.introduction,params.role_agent_id,params.location,params.id)
    db = pgDB()
    # print(sql)
    db.modify(sql)
    db.close()
    
    
    # k = embeddingDB.VectorDB()
    # k.getCollection(title)
    # print()
    rs["data"] = "修改成功"
    return rs

    
@router.post("/getDeviceList")
def getDeviceList(params:Device):
    rs = {"code":200,"msg":"创建成功","data":{}}
    # title = params.title
    # print(params)
    
    sql = '''
    SELECT *
    FROM device ORDER BY create_time desc
    '''
    db = pgDB()
    data = db.select(sql)
    db.close()
    
    # data = [ convert_keys_to_camel(Device(**d).dict()) for d in data]
    # data = data.dict()  # 将 Pydantic 模型转换为字典
    # data = convert_keys_to_camel(data)  # 将字典键转换为驼峰命名
    
    rs["data"] = data
    # print(">>",rs["data"])
    return rs
    
@router.post("/deleteDevice")
def deleteDevice(params:Device):
    rs = {"code":200,"msg":"删除成功","data":{}}
    print(params)
    sql = '''
    DELETE FROM device 
    WHERE id = '{}'
    '''.format(params.id)
    db = pgDB()
    data = db.modify(sql)
    rs["data"] = {}
    db.close()
    
    # k.delDevice(params.title)
    
    return rs
    
@router.post("/getDeviceInfo")
def getDeviceInfo(params:Device):
    rs = {"code":200,"msg":"查询成功","data":{}}
    # title = params.title
    # print(params)
    
    sql = '''
    SELECT * 
    FROM device
    WHERE id = '{}'
    '''.format(params.id)
    # print(sql)
    db = pgDB()
    
    data = db.select(sql)
    
    if data is None or len(data)==0:
        return {"code":200,"msg":"查询失败","data":{}}
    data = data[0]
    history = []
    for record in reversed(getDeviceChatRecordByDeviceId(data["device_id"])):
        history.append({"role":"user","content":record["user_question"],"create_time":record["create_time"]})
        history.append({"role":"assistant","content":record["assistant_reply"],"create_time":record["create_time"]})
    data.update({"history":history })
    # data = Device(**data)
    # data = data.dict()  # 将 Pydantic 模型转换为字典
    # data = convert_keys_to_camel(data)  # 将字典键转换为驼峰命名
    
    # DeviceInfo = xingchenCharacterAPI.character_details(device_id=data.device_id)
    # print(DeviceInfo.data)
    db.close()
    
    # rs["data"] = data
    # db.close()
    # print(">>",rs["data"])
    # print()
    # try:
    #     fileList = [{"fileName":f } for f in os.listdir("./uploadFiles/{}".format(params.id))]
    # except:
    #     fileList=[]
    # print(kList)
    # k.delDevice(params.title)
    rs["data"] = data
    return rs
    
    
